Skip to content

release: v10.19.0 — J2KDICOMHelpers Phase 2 (Pixel Data encapsulation)#455

Merged
SureshKViswanathan merged 1 commit into
mainfrom
v10.19.0-release-candidate
May 26, 2026
Merged

release: v10.19.0 — J2KDICOMHelpers Phase 2 (Pixel Data encapsulation)#455
SureshKViswanathan merged 1 commit into
mainfrom
v10.19.0-release-candidate

Conversation

@SureshKViswanathan

Copy link
Copy Markdown
Contributor

Summary

  • Adds DICOM Pixel Data encapsulation helpers to the J2KDICOMHelpers library (introduced in v10.17.0): J2KDICOMPixelDataEncapsulator.encapsulateItem(_:) + .encapsulateFrames(_:includeBOT:) for the write side, J2KDICOMPixelDataDecapsulator.extractFrames(_:) for the read side, J2KDICOMPixelDataError for typed failures.
  • ADR-004 compliant — no DICOM library dependency added anywhere; byte-layout rules codified directly from PS3.5 §A.4 / §6.4.
  • MINOR per RELEASING.md — pure additive surface on the existing library; codestream bytes byte-identical to v10.18.0.

What's New

API Description
J2KDICOMPixelDataEncapsulator.encapsulateItem(_:) Single codestream → DICOM Item bytes (header + LE u32 length + payload + optional pad)
J2KDICOMPixelDataEncapsulator.encapsulateFrames(_:includeBOT:) Multi-frame → BOT + per-frame Items + Sequence Delimitation
J2KDICOMPixelDataDecapsulator.extractFrames(_:) Reverse — parses Item sequence + strips EOC-then-pad bytes
J2KDICOMPixelDataError Sendable, Equatable error type

Correctness gate (release mode)

  • V10_31_PixelDataEncapsulationTests 12/12 PASS (encapsulateItem even+odd length, padding correctness; encapsulateFrames single+multi frame with empty and populated BOT; round-trip byte-exact; pad stripping; truncated/invalid input rejection; error type Equatable)
  • swift test --filter J2KDICOMHelpers regression 38/38 PASS (26 V10_29 Phase 1 + 12 V10_31 Phase 2)
  • swift test --filter JP3D regression 532/532 PASS (1 pre-existing skip)
  • J2KMedicalCorpusEncodePerformanceTests 2/2 PASS
  • J2KMedicalCorpusPerformanceTests 2/2 PASS
  • J2KStrictCrossCodecValidationTests 3/3 PASS

Mandatory commit gate: 7/7 PASS release mode.

Phase 2 scope rationale

The original v10.17.0 plan named Phase 2 as "DICOM file parser extraction from J2KCLI/DICOMSupport.swift". On closer inspection, full file parsing pulls in ~400 LOC of consumer-side responsibility (group 0002 walking, dataset tag walker, multi-frame layout, photometric handling). Consumers using pydicom / DICOMKit / dcm4che already do that correctly. What's been missing — and what v10.19.0 ships — is the J2K-specific wire format for the Pixel Data element: the encapsulator/decapsulator pair. This is immediately useful for the write side (encode via J2KSwift → embed in DICOM file) and replaces hand-rolled byte construction (which existed as test-scaffolding in J2KStrictCrossCodecValidationTests.swift:170-194).

Full file parser extraction stays a Phase 3 candidate.

Test plan

  • Mandatory pre-release gate (release mode)
  • Full J2KDICOMHelpers regression (38/38 PASS)
  • Full JP3D regression (532/532 PASS)
  • V10_31 parity tests (12/12 PASS — layout + round-trip + error paths)
  • README.md updated (Current Version + Previous Release + Release Status paragraph)
  • getVersion() bumped 10.18.0 → 10.19.0

🤖 Generated with Claude Code

Adds DICOM Pixel Data encapsulation helpers to the J2KDICOMHelpers
library (introduced in v10.17.0). Wraps J2K codestreams into DICOM
Pixel Data Item bytes (PS3.5 §A.4) for the write side, and parses
them back for the read side.

New public surface:

  * J2KDICOMPixelDataEncapsulator.encapsulateItem(_:) — single J2K
    codestream → one DICOM Pixel Data Item (8-byte header FFFE,E000
    + LE u32 length + payload + optional 0x00 pad per PS3.5 §6.4)

  * J2KDICOMPixelDataEncapsulator.encapsulateFrames(_:includeBOT:) —
    multiple frames → BOT (optional contents) + per-frame Items +
    Sequence Delimitation Item. BOT entries are little-endian u32
    offsets measured from the start of the first frame Item per
    current DICOM Standard.

  * J2KDICOMPixelDataDecapsulator.extractFrames(_:) — parses an
    encapsulated sequence back into per-frame J2K codestreams.
    Strips trailing 0x00 pad bytes when detected via the
    EOC-then-pad pattern (0xFF 0xD9 0x00).

  * J2KDICOMPixelDataError — Sendable, Equatable error type with
    cases: truncated, itemTagExpected, itemLengthOverrun,
    malformedSequenceDelimitation.

Write-side use case: encode an image via J2KSwift, wrap as Pixel
Data via encapsulateFrames, hand the bytes off to your DICOM
writer for insertion at (7FE0,0010) with VR OB + undefined length.

Read-side use case: extract codestreams from your DICOM library's
Pixel Data bytes via extractFrames, decode each frame via
J2KDecoder.

Phase 2 scope is narrower than the original v10.17 plan (which
contemplated full DICOM file parsing extraction). Refined to the
wire-format layer specifically:
  (a) Consumers should use their own DICOM library for file parsing
      (pydicom, DICOMKit, dcm4che — all do this correctly).
  (b) The J2K-specific wire format wasn't previously available —
      consumers had to hand-roll the byte layout (the pattern was
      test-scaffolding in J2KStrictCrossCodecValidationTests:170-194).

ADR-004 compliant: no DICOM library dependency added anywhere; rules
codified directly from PS3.5 §A.4 / §6.4. Pure additive surface on
the existing J2KDICOMHelpers library; no signature changes elsewhere;
codestream bytes byte-identical to v10.18.0.

Validation:
- V10_31_PixelDataEncapsulationTests 12/12 PASS release mode
- swift test --filter J2KDICOMHelpers regression 38/38 PASS
  (26 V10_29 Phase 1 + 12 V10_31 Phase 2)
- swift test --filter JP3D regression 532/532 PASS
- Mandatory commit gate (release mode) 7/7 PASS

MINOR per RELEASING.md — pure additive surface, no removal, no
signature change. Also bumps getVersion() 10.18.0 → 10.19.0.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@SureshKViswanathan SureshKViswanathan merged commit d294bc1 into main May 26, 2026
1 of 15 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant